package com.qa.service.impl;

import com.qa.constant.MsgConstant;
import com.qa.constant.QuestionCategoryConstant;
import com.qa.constant.QuestionConstant;
import com.qa.dto.QuestionAddDTO;
import com.qa.dto.QuestionQueryDTO;
import com.qa.entity.Category;
import com.qa.entity.CategoryQuery;
import com.qa.entity.Question;
import com.qa.entity.QuestionCategory;
import com.qa.mapper.CategoryMapper;
import com.qa.mapper.QuestionCategoryMapper;
import com.qa.mapper.QuestionMapper;
import com.qa.result.Result;
import com.qa.service.QuestionService;
import com.qa.utils.CommonUtil;
import com.qa.utils.UserUtil;
import com.qa.vo.QuestionVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author 徐
 */
@Slf4j
@Service
public class QuestionServiceImpl implements QuestionService {

    @Autowired
    private QuestionMapper questionMapper;

    @Autowired
    private QuestionCategoryMapper questionCategoryMapper;

    @Autowired
    private CategoryMapper categoryMapper;

    /**
     * 根据questions生成questionVos（为题目添加所属分类）
     *
     * @param questions List
     * @return List
     */
    private List<QuestionVO> generateQuestionVos(List<Question> questions) {
        List<QuestionVO> questionVos = new ArrayList<>();

        List<Long> questionIds = new ArrayList<>();
        questions.forEach(question -> {
            questionIds.add(question.getId());
        });
        // log.info("questionIds: " + questionIds);
        List<CategoryQuery> categoryQueries = categoryMapper.getCategoryByQuestions(questionIds);
        // log.info("categoryQueries: " + categoryQueries);
        Map<Long, List<Category>> categoryQueryMap = new HashMap<>();
        for (CategoryQuery categoryQuery : categoryQueries) {
            Category category = new Category();
            BeanUtils.copyProperties(categoryQuery, category);
            List<Category> categories = new ArrayList<>();
            // 如果题目id在map中，则添加分类，否则新建一个list
            if (categoryQueryMap.containsKey(categoryQuery.getQuestionId())) {
                categories = categoryQueryMap.get(categoryQuery.getQuestionId());
            }
            categories.add(category);
            categoryQueryMap.put(categoryQuery.getQuestionId(), categories);
        }
        // log.info("categoryQueryMap: " + categoryQueryMap);

        for (Question question : questions) {
            QuestionVO questionVO = new QuestionVO();
            BeanUtils.copyProperties(question, questionVO);
            // 题目id
            Long questionId = question.getId();

            // 设置题目所属分类
            // List<Category> categories = categoryMapper.getCategoryByQuestion(questionId);
            List<Category> categories = categoryQueryMap.get(questionId);
            questionVO.setCategories(categories);

            questionVos.add(questionVO);
        }
        return questionVos;
    }

    /**
     * 新增题目
     *
     * @param questionAddDTO 题目
     * @return 是否新增成功
     */
    @Override
    @Transactional
    public Result addQuestion(QuestionAddDTO questionAddDTO) {
        // 创建者id
        Long userId = UserUtil.getCurrentUserId();
        // 题目id为用户id+创建时间
        // TODO: 2024/3/13 修改id创建方式
        String id = userId + CommonUtil.initIdByNowTime();
        // 选择题设置
        Question question = Question.builder()
                .id(Long.valueOf(id))
                // 选项内容
                .choice(questionAddDTO.getChoice())
                // 答案
                .answer(questionAddDTO.getAnswer())
                .open(questionAddDTO.getOpen())
                .question(questionAddDTO.getQuestion())
                .creator(userId)
                // 新增题目默认状态为存在：1
                .status(QuestionConstant.STATUS_EXISTENCE)
                .kind(questionAddDTO.getKind())
                .build();

        // 应可选择多个分类
        // 分类设置
        List<Long> categoryIds = questionAddDTO.getCategoryIds();
        for (Long categoryId : categoryIds) {
            QuestionCategory questionCategory = QuestionCategory.builder()
                    .categoryId(categoryId)
                    .questionId(Long.valueOf(id))
                    // 存在
                    .status(QuestionCategoryConstant.STATUS_EXISTENCE)
                    .build();
            questionCategoryMapper.setCategoryForQuestion(questionCategory);
        }

        if (questionMapper.addQuestion(question) > 0) {
            return Result.success();
        }
        return Result.error(MsgConstant.FAIL);
    }

    /**
     * 根据分类id查询题目
     *
     * @param categoryId 分类id
     * @return 题目列表
     */
    @Override
    @Transactional
    public List<QuestionVO> getQuestionByCategoryId(Long categoryId) {
        // 题目相关属性
        List<Question> questions = questionMapper.getQuestionByCategoryId(categoryId);

        // 为题目添加所属分类
        List<QuestionVO> questionVos = generateQuestionVos(questions);

        return questionVos;
    }

    /**
     * 根据条件查询题目
     *
     * @param questionQueryDTO 题目条件
     * @return 题目列表
     */
    @Override
    @Transactional
    public List<QuestionVO> getQuestionByCondition(QuestionQueryDTO questionQueryDTO) {
        // 题目相关属性
        List<Question> questions = questionMapper.getQuestionByCondition(questionQueryDTO);

        // 为题目添加所属分类
        List<QuestionVO> questionVos = generateQuestionVos(questions);

        return questionVos;
    }

    /**
     * 根据条件查询题目（不包括该用户）
     *
     * @param questionQueryDTO 题目条件
     * @return 题目列表
     */
    @Override
    @Transactional
    public List<QuestionVO> getQuestionNotUserByCondition(QuestionQueryDTO questionQueryDTO) {
        // 题目相关属性
        List<Question> questions = questionMapper.getQuestionNotUserByCondition(questionQueryDTO);

        // 为题目添加所属分类
        List<QuestionVO> questionVos = generateQuestionVos(questions);

        return questionVos;
    }

    /**
     * 编辑题目
     *
     * @param question 题目
     * @return 是否编辑成功
     */
    @Override
    public Result editQuestion(Question question) {
        if (questionMapper.editQuestion(question) > 0) {
            return Result.success();
        }
        return Result.error(MsgConstant.FAIL);
    }

    /**
     * 删除题目（将状态改为不存在）
     *
     * @param id 题目id
     * @return 是否删除成功
     */
    @Override
    public Result deleteQuestion(Long id) {
        Integer res = questionMapper.deleteQuestion(id);
        if (res > 0) {
            return Result.success();
        }
        return Result.error(MsgConstant.DELETE_FAIL);
    }

    /**
     * 批量删除题目（将状态改为不存在）
     *
     * @param ids 题目id
     * @return 是否删除成功
     */
    @Override
    public Result deleteQuestions(List<Long> ids) {
        Integer res = questionMapper.deleteQuestions(ids);
        if (res == ids.size()) {
            return Result.success();
        } else if (res > 0 && res < ids.size()) {
            return Result.error(MsgConstant.DELETE_FAIL_PARTLY);
        } else {
            return Result.error(MsgConstant.DELETE_FAIL);
        }
    }
}
